package android.support.v4.os;

import java.lang.reflect.Field;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import com.edroid.autorunner.um.UserInfo;
import com.edroid.autorunner.um.UserManager;

/**
 * 
 * @author YYichou
 *
 */
public class EConnectivityManager extends EHook {

	@Override
	public String getClassName() {
		return ConnectivityManager.class.getName();
	}

	@Override
	public void hook() {
		findAndHookMethod("getActiveNetworkInfo", this);
		findAndHookMethod("getAllNetworkInfo", this);
		findAndHookMethod("getNetworkInfo", int.class, this);
	}
	
	private void setFiled(Object obj, String name, Object newValue) {
		try {
			Field field = obj.getClass().getDeclaredField(name);
			field.setAccessible(true);
			field.set(obj, newValue);
		} catch (Exception e) {
		}
	}
	
	private void setMobileNetworkInfo(NetworkInfo networkInfo, UserInfo userInfo) {
		setFiled(networkInfo, "mState", NetworkInfo.State.CONNECTED);
		setFiled(networkInfo, "mDetailedState", NetworkInfo.DetailedState.CONNECTED);
		setFiled(networkInfo, "mIsAvailable", true);
		setFiled(networkInfo, "mExtraInfo", userInfo.getNetExtra());
		
		setFiled(networkInfo, "mNetworkType", userInfo.getNetworkType());
		setFiled(networkInfo, "mTypeName", userInfo.getNetworkTypeName());

		//注意此字段是 TelephonyManager.NETWORK_TYPE_ 取值
		setFiled(networkInfo, "mSubtype", userInfo.getSimNetworkType());
		setFiled(networkInfo, "mSubtypeName", userInfo.getSimNetworkTypeName());
	}

	@Override
	protected void after(String name, Object[] args, MethodHookParam param) {
//		log.i("econn", "after " + name + " ret=" + param.getResult());
		UserInfo userInfo = UserManager.currentUserInfo();
		
		if("getActiveNetworkInfo".equals(name)) {
			NetworkInfo networkInfo = (NetworkInfo) param.getResult();
			
			if(userInfo.getNetworkType() == ConnectivityManager.TYPE_WIFI) {
				
			} else if(userInfo.getNetworkType() == ConnectivityManager.TYPE_MOBILE) {
				setMobileNetworkInfo(networkInfo, userInfo);
			}
			
			param.setResult(networkInfo);
		} else if("getNetworkInfo".equals(name)) {
			int i = (Integer) args[0];
			NetworkInfo networkInfo = (NetworkInfo) param.getResult();
			
//			log.i("econn", "getNetworkInfo(" + args[0]);
			if(userInfo.getNetworkType() == ConnectivityManager.TYPE_WIFI) {
				if(i == ConnectivityManager.TYPE_WIFI) {
					setFiled(networkInfo, "mExtraInfo", userInfo.getNetExtra());
				} else {
					setFiled(networkInfo, "mDetailedState", NetworkInfo.DetailedState.DISCONNECTED);
					setFiled(networkInfo, "mState", NetworkInfo.State.DISCONNECTED);
					setFiled(networkInfo, "mIsAvailable", false);
				}
			} else if(userInfo.getNetworkType() == ConnectivityManager.TYPE_MOBILE) {
				if(i == ConnectivityManager.TYPE_MOBILE) {
					setMobileNetworkInfo(networkInfo, userInfo);
				} else {
					setFiled(networkInfo, "mState", NetworkInfo.State.DISCONNECTED);
					setFiled(networkInfo, "mDetailedState", NetworkInfo.DetailedState.DISCONNECTED);
					setFiled(networkInfo, "mIsAvailable", false);
				}
			}
			
			param.setResult(networkInfo);
		}
		
		super.after(name, args, param);
	}
}
